// file:src/include/os/fsal.h
// autor:jiangxinpeng
// time:2021.2.23
// copyright:(C) by jiangxinpeng,All right are reserved.

#ifndef __OS_FS_FSAL_H
#define __OS_FS_FSAL_H

#include <os/spinlock.h>
#include <os/dirent.h>
#include <os/fd.h>
#include <lib/type.h>
#include <lib/list.h>
#include <sys/status.h>
#include <sys/select.h>
#include <sys/time.h>
#include <arch/atomic.h>

#define LOCAL_FILE_MAX 256
#define MAX_PATH_LEN 256

#define SELECT_FDS_NUM 4

#define RW_BUFF_SIZE 512   // when copy from user,need to use a temp buffer
#define RW_CHUNK_SIZE 8192 // when copy from user,nend to make data to chunk to rw

// check whether file object ref is 0
#define FILE_CLOSE_NEED(file) (FsalFileNeedClose(file))

typedef int (*select_t)(int, fd_set_t *, fd_set_t *, fd_set_t *, timeval_t *);

typedef struct fsal
{
    uint8_t *name;   // fsal name
    char **subtable; // fs subtable
    int (*open)(const char *name, int flags);
    int (*close)(int fp);
    int (*read)(int fp, void *buff, size_t size);
    int (*write)(int fp, void *buff, size_t size);
    int (*fastread)(int fp, void *buff, size_t size);
    int (*fastwrite)(int fp, void *buff, size_t size);
    int (*fastio)(int fp, int cmd, void *arg);
    int (*ioctl)(int fp, int cmd, void *arg);
    int (*delfile)(char *name);
    int (*deldir)(char *dirname);
    int (*rename)(const char *old_name, const char *new_name);
    int (*renamedir)(const char *old_dir, const char *old_new);
    int (*opendir)(const char *dir);
    int (*closedir)(int dir);
    int (*rewinddir)(int dir);
    int (*mkdir)(const char *dir, mode_t mode);
    int (*rmdir)(const char *dir);
    int (*mkfs)(const char *, char *, uint32_t);
    int (*mount)();
    int (*unmount)();
    int (*readdir)(int dir, dirent_t *dirent);
    size_t (*fsize)(int fp);
    int (*fsync)(int fp);
    int (*unlink)(const char *path);
    int (*lseek)(int fd, offset_t off, int where);
    int (*access)(const char *path, mode_t mode);
    int (*status)(const char *path, status_t *status);
    int (*fstatus)(int handle, status_t *status);
    int (*incref)(int idx);
    int (*decref)(int idx);
    int (*chmod)(const char *path, mode_t mode);
    int (*fchmod)(int idx, mode_t mode);
    int (*feof)(int idx);
    int (*ferror)(int idx);
    int (*ftruncate)(int fd, offset_t off);
    int (*utime)();
    int (*rewind)();
    int (*ftell)(int fd);
    int (*chdir)();
    int (*fctnl)();
    int (*error)();
    int (*select)();
    void *(*mmap)(int fd, void *addr, size_t len, int prot, int flags, offset_t off);
    list_t list;
    void *extension; // fs extension
} fsal_t;

typedef struct
{
    file_fd_t fd[LOCAL_FILE_MAX]; // manager all local file descript
    char cwd[MAX_PATH_LEN+1];       // current work dir
    spinlock_t lock;              // manager lock
} file_manager_t;

typedef struct mount
{
    char devpath[MAX_PATH_LEN];
    char abspath[MAX_PATH_LEN];
    char path[MAX_PATH_LEN];
    int driver;
}mount_t; //mount point info

// define file fsal
PUBLIC fsal_t fsif;
PUBLIC fsal_t pipeif_rd;
PUBLIC fsal_t pipeif_wr;
PUBLIC fsal_t netif_fsal;

int FsalInit();
int FsalDiskMountInit();
int FsalDiskMount(char *path, int max);
int SysMountInfo(mount_t *mt, uint32_t count);

#endif